package com.waikuai.shop.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.waikuai.shop.common.result.Result;
import com.waikuai.shop.dto.CreateOrderDTO;
import com.waikuai.shop.dto.OrderQueryDTO;
import com.waikuai.shop.service.OrderService;
import com.waikuai.shop.service.UserService;
import com.waikuai.shop.util.JwtUtil;
import com.waikuai.shop.vo.LogisticsVO;
import com.waikuai.shop.vo.OrderDetailVO;
import com.waikuai.shop.vo.OrderListVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 订单控制器
 * @author waikuai
 */
@Slf4j
@RestController
@RequestMapping("/orders")
@RequiredArgsConstructor
@Validated
public class OrderController {

    private final OrderService orderService;
    private final UserService userService;
    private final JwtUtil jwtUtil;

    /**
     * 创建订单
     */
    @PostMapping
    public Result<Long> createOrder(
            @Valid @RequestBody CreateOrderDTO createOrderDTO,
            HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            Long orderId = orderService.createOrder(createOrderDTO, userId);
            log.info("创建订单成功，订单ID: {}, 用户ID: {}", orderId, userId);
            return Result.success("创建订单成功", orderId);
        } catch (Exception e) {
            log.error("创建订单失败: {}", e.getMessage(), e);
            return Result.error("创建订单失败: " + e.getMessage());
        }
    }

    /**
     * 支付订单
     */
    @PostMapping("/{orderId}/pay")
    public Result<String> payOrder(
            @PathVariable @NotNull Long orderId,
            @RequestParam @NotNull String paymentPassword,
            HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            boolean result = orderService.payOrder(orderId, userId, paymentPassword);
            if (result) {
                log.info("订单支付成功，订单ID: {}, 用户ID: {}", orderId, userId);
                return Result.success("订单支付成功");
            } else {
                return Result.error("订单支付失败");
            }
        } catch (Exception e) {
            log.error("订单支付失败: {}", e.getMessage(), e);
            return Result.error("订单支付失败: " + e.getMessage());
        }
    }

    /**
     * 查询订单列表（分页）
     */
    @GetMapping("/page")
    public Result<IPage<OrderListVO>> getOrderPage(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "20") Integer size,
            @RequestParam(required = false) Integer orderStatus,
            HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            OrderQueryDTO queryDTO = new OrderQueryDTO();
            queryDTO.setUserId(userId);
            queryDTO.setCurrent(current);
            queryDTO.setSize(size);
            queryDTO.setOrderStatus(orderStatus);

            IPage<OrderListVO> orderPage = orderService.getOrderPage(queryDTO);
            log.info("分页查询订单列表成功，用户ID: {}, 总数: {}", userId, orderPage.getTotal());
            return Result.success("查询订单列表成功", orderPage);
        } catch (Exception e) {
            log.error("分页查询订单列表失败: {}", e.getMessage(), e);
            return Result.error("查询订单列表失败");
        }
    }

    /**
     * 查询订单列表（不分页）
     */
    @GetMapping
    public Result<List<OrderListVO>> getOrderList(
            @RequestParam(required = false) Integer orderStatus,
            HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            List<OrderListVO> orderList = orderService.getOrderList(userId, orderStatus);
            log.info("查询订单列表成功，用户ID: {}, 数量: {}", userId, orderList.size());
            return Result.success("查询订单列表成功", orderList);
        } catch (Exception e) {
            log.error("查询订单列表失败: {}", e.getMessage(), e);
            return Result.error("查询订单列表失败");
        }
    }

    /**
     * 查询订单详情
     */
    @GetMapping("/{orderId}")
    public Result<OrderDetailVO> getOrderDetail(
            @PathVariable @NotNull Long orderId,
            HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            OrderDetailVO orderDetail = orderService.getOrderDetail(orderId, userId);
            log.info("查询订单详情成功，订单ID: {}, 用户ID: {}", orderId, userId);
            return Result.success("查询订单详情成功", orderDetail);
        } catch (Exception e) {
            log.error("查询订单详情失败: {}", e.getMessage(), e);
            return Result.error("查询订单详情失败: " + e.getMessage());
        }
    }

    /**
     * 取消订单
     */
    @PutMapping("/{orderId}/cancel")
    public Result<String> cancelOrder(
            @PathVariable @NotNull Long orderId,
            HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            boolean result = orderService.cancelOrder(orderId, userId);
            if (result) {
                log.info("取消订单成功，订单ID: {}, 用户ID: {}", orderId, userId);
                return Result.success("取消订单成功");
            } else {
                return Result.error("取消订单失败");
            }
        } catch (Exception e) {
            log.error("取消订单失败: {}", e.getMessage(), e);
            return Result.error("取消订单失败: " + e.getMessage());
        }
    }

    /**
     * 获取订单物流信息
     */
    @GetMapping("/{orderId}/logistics")
    public Result<LogisticsVO> getOrderLogistics(
            @PathVariable @NotNull Long orderId,
            HttpServletRequest request) {
        try {
            Long userId = getCurrentUserId(request);
            LogisticsVO logistics = orderService.getOrderLogistics(orderId, userId);
            log.info("获取订单物流信息成功，订单ID: {}, 用户ID: {}", orderId, userId);
            return Result.success("获取物流信息成功", logistics);
        } catch (Exception e) {
            log.error("获取订单物流信息失败: {}", e.getMessage(), e);
            return Result.error("获取物流信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取当前登录用户ID
     * 优先使用Spring Security认证，如果不可用则从HTTP Token中获取
     */
    private Long getCurrentUserId() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.getPrincipal() != null) {
                Object principal = authentication.getPrincipal();
                if (principal instanceof UserDetails) {
                    UserDetails userDetails = (UserDetails) principal;
                    String username = userDetails.getUsername();
                    
                    com.waikuai.shop.entity.User user = userService.findByUsername(username);
                    if (user != null) {
                        return user.getId();
                    }
                }
            }
        } catch (Exception e) {
            log.debug("从Spring Security获取用户ID失败，尝试从Token获取: {}", e.getMessage());
        }
        
        throw new RuntimeException("用户未登录，请先登录");
    }

    /**
     * 从HTTP请求中获取用户ID（备用方案）
     */
    private Long getUserIdFromToken(HttpServletRequest request) {
        try {
            String bearerToken = request.getHeader("Authorization");
            if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
                String token = bearerToken.substring(7);
                
                if (!jwtUtil.validateTokenFormat(token)) {
                    log.warn("Token格式无效");
                    return null;
                }
                
                if (jwtUtil.isTokenExpired(token)) {
                    log.warn("Token已过期");
                    return null;
                }
                
                Long userId = jwtUtil.getUserIdFromToken(token);
                if (userId != null) {
                    log.debug("从Token中获取用户ID成功: {}", userId);
                    return userId;
                }
            }
        } catch (Exception e) {
            log.error("从Token中获取用户ID失败: {}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取当前登录用户ID（兼容多种方式）
     */
    private Long getCurrentUserId(HttpServletRequest request) {
        try {
            return getCurrentUserId();
        } catch (RuntimeException e) {
            Long userId = getUserIdFromToken(request);
            if (userId != null) {
                return userId;
            }
            log.warn("获取用户ID失败: Spring Security和Token都不可用");
            throw new RuntimeException("用户未登录，请先登录");
        }
    }

    /**
     * 管理员查询所有订单列表（分页，支持条件查询）
     */
    @GetMapping("/admin/page")
    public Result<IPage<OrderListVO>> getAdminOrderPage(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "20") Integer size,
            @RequestParam(required = false) String orderNo,
            @RequestParam(required = false) Integer orderStatus,
            @RequestParam(required = false) Integer paymentStatus,
            HttpServletRequest request) {
        try {
            // 验证是否为管理员（这里简化处理，实际应该通过Spring Security角色验证）
            Long userId = getCurrentUserId(request);
            log.debug("管理员查询订单列表，操作员ID: {}", userId);

            OrderQueryDTO queryDTO = new OrderQueryDTO();
            queryDTO.setCurrent(current);
            queryDTO.setSize(size);
            queryDTO.setOrderNo(orderNo);
            queryDTO.setOrderStatus(orderStatus);
            queryDTO.setPaymentStatus(paymentStatus);

            IPage<OrderListVO> orderPage = orderService.getAdminOrderPage(queryDTO);
            log.info("管理员分页查询订单列表成功，总数: {}", orderPage.getTotal());
            return Result.success("查询订单列表成功", orderPage);
        } catch (Exception e) {
            log.error("管理员分页查询订单列表失败: {}", e.getMessage(), e);
            return Result.error("查询订单列表失败");
        }
    }

    /**
     * 管理员查询订单详情（无需验证订单归属）
     */
    @GetMapping("/admin/{orderId}")
    public Result<OrderDetailVO> getAdminOrderDetail(
            @PathVariable @NotNull Long orderId,
            HttpServletRequest request) {
        try {
            // 验证是否为管理员
            Long userId = getCurrentUserId(request);
            log.debug("管理员查询订单详情，操作员ID: {}, 订单ID: {}", userId, orderId);

            OrderDetailVO orderDetail = orderService.getAdminOrderDetail(orderId);
            log.info("管理员查询订单详情成功，订单ID: {}", orderId);
            return Result.success("查询订单详情成功", orderDetail);
        } catch (Exception e) {
            log.error("管理员查询订单详情失败: {}", e.getMessage(), e);
            return Result.error("查询订单详情失败: " + e.getMessage());
        }
    }

    /**
     * 管理员更新订单状态
     */
    @PutMapping("/admin/{orderId}/status")
    public Result<String> updateOrderStatus(
            @PathVariable @NotNull Long orderId,
            @RequestParam @NotNull Integer orderStatus,
            HttpServletRequest request) {
        try {
            // 验证是否为管理员
            Long userId = getCurrentUserId(request);
            log.debug("管理员更新订单状态，操作员ID: {}, 订单ID: {}, 新状态: {}", userId, orderId, orderStatus);

            boolean result = orderService.updateOrderStatus(orderId, orderStatus);
            if (result) {
                log.info("管理员更新订单状态成功，订单ID: {}, 新状态: {}", orderId, orderStatus);
                return Result.success("更新订单状态成功");
            } else {
                return Result.error("更新订单状态失败");
            }
        } catch (Exception e) {
            log.error("管理员更新订单状态失败: {}", e.getMessage(), e);
            return Result.error("更新订单状态失败: " + e.getMessage());
        }
    }
}
